#pragma once

#include "../umlmodel_global.h"

#include <memory>
#include <vector>

#include "Property.h"

using std::make_shared;
using std::shared_ptr;
using std::vector;

namespace uml {
class Stereotype;

/// <summary>
/// ExtensionEnd
/// An extension end is used to tie an extension to a stereotype when extending a
/// metaclass.
/// The default multiplicity of an extension end is 0..1.
/// </summary>
class UMLMODEL_EXPORT ExtensionEnd : public Property {

public: // Constructors and destructors
    explicit ExtensionEnd(const QString& umlType="uml::ExtensionEnd");

public: // JsonSerializable override
    void fromJson(const QJsonObject& json, QStringList& errorList) override;
    void toJson(QJsonObject& json) override;

public: // Methods
    /// <summary>
    /// lowerBound
    /// The query lowerBound() returns the lower bound of the multiplicity as an
    /// Integer. This is a redefinition of the default lower bound, which normally, for
    /// MultiplicityElements, evaluates to 1 if empty.
    /// </summary>
    int lowerBound() const override;

public: // Properties
    /// <summary>
    /// lower getter
    /// This redefinition changes the default multiplicity of association ends, since
    /// model elements are usually extended by 0 or 1 instance of the extension
    /// stereotype.
    /// </summary>
    int lower() const;

    /// <summary>
    /// lower setter
    /// This redefinition changes the default multiplicity of association ends, since
    /// model elements are usually extended by 0 or 1 instance of the extension
    /// stereotype.
    /// </summary>
    void setLower(int value);

    /// <summary>
    /// type getter
    /// References the type of the ExtensionEnd. Note that this association restricts
    /// the possible types of an ExtensionEnd to only be Stereotypes.
    /// </summary>
    shared_ptr<Stereotype> type() const;

    /// <summary>
    /// type setter
    /// References the type of the ExtensionEnd. Note that this association restricts
    /// the possible types of an ExtensionEnd to only be Stereotypes.
    /// </summary>
    void setType(shared_ptr<Stereotype> value);

private: // Fields
    /// <summary>
    /// lower
    /// This redefinition changes the default multiplicity of association ends, since
    /// model elements are usually extended by 0 or 1 instance of the extension
    /// stereotype.
    /// </summary>
    const static int lower_default_;
    int lower_= lower_default_;

    /// <summary>
    /// type
    /// References the type of the ExtensionEnd. Note that this association restricts
    /// the possible types of an ExtensionEnd to only be Stereotypes.
    /// </summary>
    shared_ptr<Stereotype> type_;

};

} // namespace uml
